//--------------------------------------------------------------------------------
/*!
\file	FileIOHelpers.cpp
\author	Ben Smith
\date	09/14/2006
\brief	File that includes functions to assist with file I/O
\par	license
All content (c) 2005, DigiPen (USA) Corporation, all rights reserved.
*/
//--------------------------------------------------------------------------------

#include "FileIOHelpers.h"

//--------------------------------------------------------------------------------
/*!
\brief	Skips all characters in the given input stream until the delimiter
		character 'ch' is encountered.  'ch' is extracted from the input stream.
\author	Ben Smith
\date	09/14/2006
\param	is
	Input stream to process.
\param	ch
	Character to skip to.
\return
	Number of characters skipped.
*/
//--------------------------------------------------------------------------------
unsigned SkipToChar(std::istream& is, char ch)
{
	char chRead;
	unsigned num = 0;
	while (is >> chRead && chRead != ch)
		num++;
	return num;
}

//--------------------------------------------------------------------------------
/*!
\brief	Skips all characters in the given input stream until the delimiter
		character 'ch' is encountered.  'ch' is extracted from the input stream.
		If the end of file is encountered during this process, return false.
		Otherwise, return true.
\author	Ben Smith
\date	09/14/2006
\param	is
	Input stream to process.
\param	ch
	Character to skip to.
*/
//--------------------------------------------------------------------------------
bool SkipToCharInFile(std::istream& is, char ch)
{
	char chRead;
	while (is >> chRead && chRead != ch);
	if (is.eof())
		return false;
	return true;
}

//--------------------------------------------------------------------------------
/*!
\brief	Reads characters into a string until the delimiter 'ch' is found.
		'ch' is extracted from the input stream, but not stored.
\author	Ben Smith
\date	09/14/2006
\param	is
	Input stream to process.
\param	str
	String to fill with characters read.
\param	ch
	Delimiter character to read until.
\return
	Number of characters read.
*/
//--------------------------------------------------------------------------------
unsigned ReadToChar(std::istream& is, std::string& str, char ch)
{
	char chRead;
	while (!is.eof()) {
		chRead = static_cast<char>(is.get());
		if (chRead == ch)
			return (unsigned)str.size() + 1;
		if (IsWhitespace(chRead) && str.empty())
			continue;
		str.push_back(chRead);
	}
	return (unsigned)str.size();
}

//--------------------------------------------------------------------------------
/*!
\brief	Reads characters into a string until any delimiter in the delimiter array
	is found.  The delimiter will be extracted but not stored.
\author	Ben Smith
\date	09/14/2006
\param	is
	Input stream to process.
\param	str
	String to fill with characters read.
\param	delimArray
	Array of delimiters.
\param	numDelim
	Number of delimiters in array.
\return
	Number of characters read.
*/
//--------------------------------------------------------------------------------
unsigned ReadToChar(std::istream& is, std::string& str, char delimArray[], unsigned numDelim)
{
	char chRead;
	while (!is.eof()) {
		chRead = static_cast<char>(is.get());
		if (CharMatchInArray(chRead, delimArray, numDelim))
			return (unsigned)str.size() + 1;
		if (IsWhitespace(chRead) && str.empty())
			continue;
		str.push_back(chRead);
	}
	return (unsigned)str.size();
}

//--------------------------------------------------------------------------------
/*!
\brief	Skips all text until the delimiter character is found.
\author	Ben Smith
\date 	09/16/2006
\param	strIn
	String to process.
\param	iter
	Index of character (in string) to process from.
\param	ch
	Delimiter character.
*/
//--------------------------------------------------------------------------------
unsigned SkipToChar(const std::string& strIn, unsigned iter, char ch)
{
	unsigned num = 0;
	while (iter < strIn.size()) {
		num++;
		if (strIn[iter++] == ch)
			return num;
	}
	return num;
}

//--------------------------------------------------------------------------------
/*!
\brief	Reads all text into a string until the delimiter character is found.
\author	Ben Smith
\date 	09/16/2006
\param	strIn
	String to process.
\param	iter
	Index of character (in string) to process from.
\param	str
	String to read text into.
\param	ch
	Delimiter character.
*/
//--------------------------------------------------------------------------------
unsigned ReadToChar(const std::string& strIn, unsigned iter, std::string& str, char ch)
{
	char chRead;
	unsigned nS = 0;
	while (iter < strIn.size()) {
		chRead = strIn[iter++];
		if (chRead == ch)
			return (unsigned)str.size() + 1;
		if (IsWhitespace(chRead) && str.empty()) {
			nS++;
			continue;
		}
		str.push_back(chRead);
	}
	return (unsigned)str.size();
}


//--------------------------------------------------------------------------------
/*!
\brief	Returns true if character is a newline or whitespace.
\author	Ben Smith
\date 	09/16/2006
\param	c
	Character to process.
\return
	True is character is whitespace or newline, False otherwise.
*/
//--------------------------------------------------------------------------------
bool IsWhitespace(char c)
{
	if (c == ' ' ||
		c == '\t' ||
		c == '\n' ||
		c == '\r')
		return true;
	return false;
}

//--------------------------------------------------------------------------------
/*!
\brief	Looks for a match between a parameter character and a character array.
\author	Ben Smith
\date	09/19/2006
\param	ch
	Character to check for in the array.
\param	arr
	Array to check in.
\param	arrSize
	Size of array (number of elements).
\return
	True if match found, false otherwise.
*/
//--------------------------------------------------------------------------------
bool CharMatchInArray(char ch, char arr[], unsigned arrSize)
{
	for (unsigned i=0; i < arrSize; ++i)
		if (ch == arr[i])
			return true;
	return false;
}